package net.borlis.sample.horses.process;

import net.borlis.sample.horses.core.AppConfiguration;
import net.borlis.sample.horses.core.Horse;

import java.util.*;
import java.util.concurrent.Callable;

/**
 * Created by Alexander on 22.12.2014.
 */
public class HorseRace implements Callable<List<Map.Entry<Horse, Integer>>> {

    private static Random randomGenerator = new Random();
    private AppConfiguration configuration;

    public HorseRace(AppConfiguration appConfiguration) {
        this.configuration = appConfiguration;
    }

    public List<Map.Entry<Horse, Integer>> race() {
        Set<Map.Entry<Horse, Integer>> configSet = configuration.getOdds().entrySet();
        List<Map.Entry<Horse, Integer>> result = new ArrayList<Map.Entry<Horse, Integer>>();
        for (Map.Entry<Horse, Integer> entry : configSet) {
            result.add(new AbstractMap.SimpleEntry<Horse, Integer>(entry.getKey(), result(entry)));
        }
        Collections.sort(result, new Comparator<Map.Entry<Horse, Integer>>() {
            @Override
            public int compare(Map.Entry<Horse, Integer> o1, Map.Entry<Horse, Integer> o2) {
                return -(o1.getValue().compareTo(o2.getValue()));
            }
        });

        System.out.println("+++RACE RESULTS++");
        int index = 1;
        for (Map.Entry<Horse, Integer> entry : result) {
            System.out.println("#" + index + " horse num:" + entry.getKey().getId() + ". " + entry.getKey().getName());
            index++;
        }
        System.out.println("++++++++++++++");
        return result;
    }

    private Integer result(Map.Entry<Horse, Integer> horseIntegerEntry) {
        Integer random = (int) (Math.abs(randomGenerator.nextGaussian()) * Integer.valueOf(horseIntegerEntry.getValue()));
        return random != 0 ? random : Integer.valueOf(horseIntegerEntry.getValue());
    }

    @Override
    public List<Map.Entry<Horse, Integer>> call() throws Exception {
        return race();
    }
}
